package com.example.xunai.controller;

import com.example.xunai.dto.request.ai.ChatRequest;
import com.example.xunai.dto.request.ai.StreamChatRequest;
import com.example.xunai.dto.response.ai.ChatResponse;
import com.example.xunai.dto.response.system.ApiResponse;
import com.example.xunai.dto.response.system.ModelConfigResponse;
import com.example.xunai.entity.User;
import com.example.xunai.service.ai.AiChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@RestController
@RequestMapping("/api/ai")
@RequiredArgsConstructor
public class AiController {

    private final AiChatService aiChatService;

    // 存储活跃的请求ID，防止重复请求
    private final Map<String, Long> activeRequests = new ConcurrentHashMap<>();
    private static final long REQUEST_TIMEOUT = 120000; // 2分钟

    /**
     * 通用流式聊天接口 - 支持多模型切换
     */
    @GetMapping(value = "/chat/stream", produces = "text/event-stream")
    public SseEmitter streamChat(@RequestParam String message,
                                 @RequestParam(required = false) String sessionId,
                                 @RequestParam(required = false) Long conversationId,
                                 @RequestParam(defaultValue = "deepseek") String modelType,
                                 @RequestParam(required = false) String requestId,
                                 HttpServletRequest httpRequest,
                                 HttpSession httpSession) {

        // 验证用户登录
        User user = (User) httpSession.getAttribute("user");
        if (user == null) {
            throw new RuntimeException("未登录");
        }

        // 获取或创建会话ID
        String finalSessionId = (sessionId != null) ? sessionId : getOrCreateSessionId(httpRequest);

        // 生成或使用传入的请求ID
        String finalRequestId = (requestId != null && !requestId.trim().isEmpty()) ?
                requestId : generateRequestId();

        // 检查重复请求
        if (isDuplicateRequest(finalRequestId)) {
            log.warn("检测到重复请求，请求ID: {}, 用户ID: {}, 会话ID: {}",
                    finalRequestId, user.getId(), finalSessionId);
            SseEmitter emitter = new SseEmitter();
            emitter.completeWithError(new RuntimeException("重复请求，请稍后再试"));
            return emitter;
        }

        // 记录活跃请求
        activeRequests.put(finalRequestId, System.currentTimeMillis());

        log.info("处理流式请求，模型: {}, 用户ID: {}, 会话ID: {}, 对话ID: {}, 消息长度: {}, 请求ID: {}",
                modelType, user.getId(), finalSessionId, conversationId, message.length(), finalRequestId);

        // 创建StreamChatRequest并调用AiChatService
        StreamChatRequest request = StreamChatRequest.of(message, finalSessionId, conversationId, user.getId(), modelType, finalRequestId);
        SseEmitter emitter = aiChatService.streamChat(request);

        // 设置完成回调，清理活跃请求
        emitter.onCompletion(() -> {
            activeRequests.remove(finalRequestId);
            log.info("请求完成，清理活跃请求: {}", finalRequestId);
        });

        emitter.onTimeout(() -> {
            activeRequests.remove(finalRequestId);
            log.warn("请求超时，清理活跃请求: {}", finalRequestId);
        });

        emitter.onError((error) -> {
            activeRequests.remove(finalRequestId);
            log.error("请求错误，清理活跃请求: {}, 错误: {}", finalRequestId, error.getMessage());
        });

        return emitter;
    }

    /**
     * 同步聊天接口 - 支持多模型切换（返回ChatResponse）
     */
    @PostMapping("/chat/message")
    public ResponseEntity<ApiResponse<ChatResponse>> sendMessage(
            @RequestParam String message,
            @RequestParam String sessionId,
            @RequestParam(required = false) Long conversationId,
            @RequestParam(defaultValue = "deepseek") String modelType,
            @RequestParam(required = false) String requestId,
            HttpSession session) {

        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResponseEntity.status(401).body(ApiResponse.error("401", "未登录"));
        }

        // 检查重复请求
        String finalRequestId = (requestId != null && !requestId.trim().isEmpty()) ?
                requestId : generateRequestId();
        if (isDuplicateRequest(finalRequestId)) {
            log.warn("检测到重复同步请求，请求ID: {}, 用户ID: {}", finalRequestId, user.getId());
            return ResponseEntity.status(429).body(ApiResponse.error("429", "重复请求，请稍后再试"));
        }

        activeRequests.put(finalRequestId, System.currentTimeMillis());

        log.info("接收到同步聊天请求，模型: {}, 用户ID: {}, 会话ID: {}, 对话ID: {}, 消息长度: {}, 请求ID: {}",
                modelType, user.getId(), sessionId, conversationId, message.length(), finalRequestId);

        try {
            // 创建ChatRequest并调用AiChatService
            ChatRequest request = ChatRequest.of(message, sessionId, conversationId, user.getId(), modelType);
            ChatResponse response = aiChatService.getAiResponse(request);
            activeRequests.remove(finalRequestId);
            return ResponseEntity.ok(ApiResponse.success(response));
        } catch (Exception e) {
            log.error("处理聊天请求失败", e);
            activeRequests.remove(finalRequestId);
            return ResponseEntity.status(500).body(ApiResponse.error("500", "处理请求失败: " + e.getMessage()));
        }
    }

    /**
     * 异步聊天接口
     */
    @PostMapping("/async/chat")
    public ResponseEntity<ApiResponse<String>> asyncChat(
            @RequestParam String message,
            @RequestParam String sessionId,
            @RequestParam(required = false) Long conversationId,
            @RequestParam(defaultValue = "deepseek") String modelType,
            HttpSession session) {

        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResponseEntity.status(401).body(ApiResponse.error("401", "未登录"));
        }

        log.info("接收到异步聊天请求，模型: {}, 用户ID: {}, 会话ID: {}, 对话ID: {}",
                modelType, user.getId(), sessionId, conversationId);

        try {
            // 创建ChatRequest并调用AiChatService
            ChatRequest request = ChatRequest.of(message, sessionId, conversationId, user.getId(), modelType);
            String requestId = aiChatService.getAiResponseAsync(request);

            return ResponseEntity.ok(ApiResponse.success("请求已提交", requestId));
        } catch (Exception e) {
            log.error("处理异步聊天请求失败", e);
            return ResponseEntity.status(500).body(ApiResponse.error("500", "处理请求失败: " + e.getMessage()));
        }
    }

    /**
     * 查询异步结果
     */
    @GetMapping("/async/result/{requestId}")
    public ResponseEntity<ApiResponse<String>> getAsyncResult(
            @PathVariable String requestId,
            HttpSession session) {

        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResponseEntity.status(401).body(ApiResponse.error("401", "未登录"));
        }

        log.info("查询异步结果: {}", requestId);

        try {
            String result = aiChatService.getAsyncResult(requestId);

            if (result != null) {
                return ResponseEntity.ok(ApiResponse.success("请求完成", result));
            } else {
                return ResponseEntity.ok(ApiResponse.success("请求处理中", null));
            }
        } catch (Exception e) {
            log.error("查询异步结果失败", e);
            return ResponseEntity.status(500).body(ApiResponse.error("500", "查询失败: " + e.getMessage()));
        }
    }

    /**
     * 获取流式消息缓存（用于恢复中断的对话）
     */
    @GetMapping("/streaming/{conversationId}")
    public ResponseEntity<ApiResponse<Object>> getStreamingMessages(
            @PathVariable Long conversationId,
            HttpSession session) {

        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResponseEntity.status(401).body(ApiResponse.error("401", "未登录"));
        }

        try {
            var messages = aiChatService.getStreamingMessages(conversationId);
            return ResponseEntity.ok(ApiResponse.success(messages));
        } catch (Exception e) {
            log.error("获取流式消息失败", e);
            return ResponseEntity.status(500).body(ApiResponse.error("500", "获取失败: " + e.getMessage()));
        }
    }

    /**
     * 获取支持的模型列表
     */
    @GetMapping("/models")
    public ResponseEntity<ApiResponse<ModelConfigResponse>> getSupportedModels(HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResponseEntity.status(401).body(ApiResponse.error("401", "未登录"));
        }

        try {
            ModelConfigResponse models = aiChatService.getSupportedModels();
            return ResponseEntity.ok(ApiResponse.success(models));
        } catch (Exception e) {
            log.error("获取模型列表失败", e);
            return ResponseEntity.status(500).body(ApiResponse.error("500", "获取模型列表失败: " + e.getMessage()));
        }
    }

    /**
     * 停止生成接口
     */
    @PostMapping("/stop")
    public ResponseEntity<ApiResponse<Object>> stopGeneration(@RequestBody StopRequest request, HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResponseEntity.status(401).body(ApiResponse.error("401", "未登录"));
        }

        log.info("收到停止请求，用户ID: {}, 会话ID: {}",
                user.getId(), request.getSessionId());

        try {
            // 直接调用停止方法
            aiChatService.setStreamStopFlag(request.getSessionId());

            // 如果有请求ID，清理活跃请求
            if (request.getRequestId() != null) {
                activeRequests.remove(request.getRequestId());
            }

            return ResponseEntity.ok(ApiResponse.success("停止请求已发送"));
        } catch (Exception e) {
            log.error("处理停止请求失败", e);
            return ResponseEntity.status(500).body(ApiResponse.error("500", "停止失败: " + e.getMessage()));
        }
    }

    // 辅助方法
    private String getOrCreateSessionId(HttpServletRequest request) {
        String sessionId = request.getParameter("sessionId");
        if (sessionId != null && !sessionId.trim().isEmpty()) {
            return sessionId;
        }

        return "session_" + System.currentTimeMillis() + "_" +
                UUID.randomUUID().toString().substring(0, 8);
    }

    private String generateRequestId() {
        return "req_" + System.currentTimeMillis() + "_" +
                UUID.randomUUID().toString().substring(0, 8);
    }

    private boolean isDuplicateRequest(String requestId) {
        // 清理过期的请求
        cleanExpiredRequests();

        // 检查是否存在相同的请求ID
        return activeRequests.containsKey(requestId);
    }

    private void cleanExpiredRequests() {
        long currentTime = System.currentTimeMillis();
        activeRequests.entrySet().removeIf(entry ->
                (currentTime - entry.getValue()) > REQUEST_TIMEOUT
        );
    }

    // 停止请求类
    public static class StopRequest {
        private String sessionId;
        private String requestId;

        public String getSessionId() { return sessionId; }
        public void setSessionId(String sessionId) { this.sessionId = sessionId; }
        public String getRequestId() { return requestId; }
        public void setRequestId(String requestId) { this.requestId = requestId; }
    }
}